# -*- coding: utf-8 -*-
# Gestión de la configuración de proyectos, documentación y generación de ficheros y packages.

## vipera, un diseñador de aplicaciones para Python
##     Copyright (C) 2011 Ángel Luis García García
##
##    This program is free software: you can redistribute it and/or modify
##    it under the terms of the GNU General Public License as published by
##    the Free Software Foundation, either version 3 of the License, or
##    (at your option) any later version.
##
##    This program is distributed in the hope that it will be useful,
##    but WITHOUT ANY WARRANTY; without even the implied warranty of
##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##    GNU General Public License for more details.
##
##    You should have received a copy of the GNU General Public License
##    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import wx
import wx.lib.imagebrowser as ib
import wx.lib.agw.hyperlink as enlace_web
import wx.lib.agw.pybusyinfo as PBI

import os
import codecs
import zipfile
import datetime
import shutil

from conf_proyecto_vista import panel_conf_vipera
from codigo_modulo_vipera import codigo_modulo as codigo_modulo_actual
from configuracion_vipera import proy_por_defecto, enter
from licencias_vipera import f_abrir_ficheros_lic, dialogo_licencias
from licencias_vipera import lic_param, f_param_lic, lic_modul, f_mostrar_info
from doc_proyecto_vipera import doc_proyecto, doc_packages, doc_base, doc_modulos
from i18n_vipera import t

class conf_vipera(panel_conf_vipera):
    '''Panel de configuración del proyecto'''
    def __init__(self, parent, panel_principal, idioma = None):
        '''Constructor de clase'''        
        panel_conf_vipera.__init__(self, parent)
        self.panel_principal = panel_principal
        self.packages = None
        self.l = idioma
        # Cambiamos idioma a los widgets.
        self.m_listbook_designer.SetPageText(0,t(u'Configurador',self.l))
        self.m_panel_configurador.SetToolTipString(t(u'Configuración del proyecto',self.l))
        self.m_listbook_designer.SetPageText(1,t(u'Ficheros',self.l))
        self.m_panel_generador.SetToolTipString(t(u'Creación de ficheros y packages',self.l))
        self.m_listbook_designer.SetPageText(2,t(u'Documentación',self.l))
        self.m_panel_documentacion.SetToolTipString(t(u'Documentación del proyecto',self.l))
        self.m_notebook_configurador.SetPageText(0, t(u'Definición', self.l))
        self.m_notebook_configurador.SetPageText(1, t(u'Módulo', self.l))
        self.m_notebook_configurador.SetPageText(5, t(u'Objetivo', self.l))
        self.m_notebook_configurador.SetPageText(6, t(u'Notas', self.l))
        self.m_staticText_nombre_proy.SetLabel(t(u"Nombre del proyecto",self.l))
        self.m_staticText_version.SetLabel(t(u'Versión',self.l))
        self.m_staticText_desarrollador.SetLabel(t(u'Desarrollador',self.l))
        self.m_staticText_grupo.SetLabel(t(u'Grupo',self.l))
        self.m_staticText_fecha.SetLabel(t(u'Fecha creación',self.l))
        self.m_staticText_indent.SetLabel(t(u'Indentación',self.l))
        self.m_staticText_codif.SetLabel(t(u'Codificación',self.l))
        self.m_checkBox_mod_prin.SetLabel(t(u'Crear módulo principal',self.l))
        self.m_staticText_nombre_modulo_p.SetLabel(t(u'Nombre del módulo',self.l))
        self.m_checkBox_script_eje.SetLabel(t(u'Hacer script ejecutable', self.l))
        self.m_checkBox_crear_mod_eje.SetLabel(t(u'Crear módulo ejecutable (chmod +x modulo_principal.py)', self.l))
        self.m_checkBox_cabecera_vipera.SetLabel(t(u'Incluir cabecera de información generada por la aplicación', self.l))
        self.m_button_crearREADME.SetLabel(t(u'Crear plantilla', self.l))
        self.m_button_borrar_README.SetLabel(t(u'Borrar todo', self.l))
        self.m_button_borrar_HISTORY.SetLabel(t(u'Borrar todo', self.l))
        self.m_button_borrar_LICENSE.SetLabel(t(u'Borrar todo', self.l))
        self.m_button_crearLICENSE.SetLabel(t(u'Crear plantilla', self.l))
        self.m_choice_licencias.SetToolTipString(t(u'Seleccionar licencia', self.l))
        self.m_bpButton_info.SetToolTipString(t(u'Ayuda sobre la licencia seleccionada', self.l))
        self.m_checkBox_aplic_lic_mod.SetLabel(t(u'Aplicar en módulos', self.l))
        self.m_button_avatar.SetLabel(t(u'Buscar imagen', self.l))
        self.m_button_eliminar_imagen.SetLabel(t(u'Eliminar imagen', self.l))
        self.m_radioBtn_carpeta.SetLabel(t(u'Una única carpeta', self.l))
        self.m_radioBtn_packages.SetToolTipString(t(u'Organizar código en una única carpeta', self.l))
        self.m_radioBtn_carpeta.SetToolTipString(t(u'Organizar código en packages', self.l))
        self.m_checkBox_modulos.SetLabel(t(u'Incluir módulos', self.l))
        self.m_checkBox_carpeta.SetLabel(t(u'Carpeta', self.l))
        self.m_checkBox_carpeta.SetToolTipString(t(u'Guardar código en una carpeta', self.l))
        self.m_checkBox_zip.SetToolTipString(t(u'Guardar código en un fichero comprimido ZIP', self.l))
        self.m_button_ruta_carpeta.SetLabel(t(u'Ruta', self.l))
        self.m_button_ruta_zip.SetLabel(t(u'Ruta', self.l))
        self.m_staticText_nombre_fichero_zip.SetLabel(t(u'Nombre', self.l))
        self.m_checkBox_crear_LICENSE.SetToolTipString(t(u'Crear fichero LICENSE', self.l))
        self.m_checkBox_crear_README.SetToolTipString(t(u'Crear fichero README', self.l))
        self.m_checkBox_crear_HISTORY.SetToolTipString(t(u'Crear fichero HISTORY', self.l))
        self.m_button_generar.SetLabel(t(u'Generar', self.l))
        self.m_checkBox_proyecto_doc.SetLabel(t(u'Proyecto', self.l))
        self.m_checkBox_modulos_doc.SetLabel(t(u'Módulos', self.l))
        self.m_checkBox_init_py.SetLabel(t(u'Crear __init__.py', self.l))
        self.m_checkBox_TXT_doc.SetToolTipString(t(u'Salida en fichero de texto', self.l))
        self.m_checkBox_HTML_doc.SetToolTipString(t(u'Salida en fichero html', self.l))
        self.m_staticText_nombre_txt.SetLabel(t(u'Nombre', self.l))
        self.m_staticText_nombre_html.SetLabel(t(u'Nombre', self.l))
        self.m_button_ruta_doc_txt.SetLabel(t(u'Ruta', self.l))
        self.m_button_ruta_doc_html.SetLabel(t(u'Ruta', self.l))
        self.m_button_generar_doc.SetLabel(t(u'Generar', self.l))
        self.m_notebook_modulos_doc.SetPageText(0, t(u'Módulos', self.l))
        self.m_panel_mod_mod.SetToolTipString(t(u'Módulos del proyecto', self.l))
        self.m_notebook_modulos_doc.SetPageText(1, t(u'Elementos de módulo', self.l))
        self.m_panel_mod_extra.SetLabel(t(u'Extra', self.l))
        self.m_staticText_alto_ogl.SetLabel(t(u'Altura', self.l))
        self.m_staticText_ancho_ogl.SetLabel(t(u'Anchura', self.l))
        # Cambiamos idioma de items de proyecto.
        lista_items = [t(u'Definición', self.l), t(u'Objetivo', self.l),
                       t(u'Notas', self.l), u'Avatar', 'README', 'LICENSE', 'HISTORY'] 
        self.m_checkList_proy_doc.SetItems(lista_items)
        # Cambiamos idioma de elementos de módulo.
        lista_items = [t(u'Documentación', self.l), u'Imports',
                       t(u'Constantes', self.l), t(u'Registros', self.l),
                       t(u'Funciones', self.l), t(u'Clases', self.l),
                       t(u'Diagrama de clases', self.l), t(u'Código principal', self.l)] 
        self.m_checkList_elem_mod_doc.SetItems(lista_items)
        
        # Imágenes.
        il = wx.ImageList(48, 48)
        imagenes = [u'recursos/images/datos_vipera.png',
                    u'recursos/images/generador_vipera.png',
                    u'recursos/images/doc_vipera.png']
        for imagen in imagenes :
            bmp = wx.Bitmap(imagen, wx.BITMAP_TYPE_ANY)
            il.Add(bmp)
        self.m_listbook_designer.AssignImageList(il)
        self.m_listbook_designer.SetPageImage(0,0)
        self.m_listbook_designer.SetPageImage(1,1)
        self.m_listbook_designer.SetPageImage(2,2)
        
    def referencia_package(self, package):
        '''Método para incluir referencia de packages'''
        self.packages = package
        
    def __pedir_carpeta(self):
        '''Petición de elección de carpeta'''
        dlg = wx.DirDialog(self, t("Elige una carpeta:", self.l),
                           style=wx.DD_DEFAULT_STYLE)
        ret = None
        if dlg.ShowModal() == wx.ID_OK:
            ret = dlg.GetPath()
        # Limpiamos memoria
        dlg.Destroy()
        # Devolvemos ruta.
        return ret

    def OnAvatar(self, event):
        '''Event Handler para incluir avatar'''
        # Directorio de la aplicación.
        dir_inicial = os.getcwd()
        # Abrimos el diálogo para buscar imagen de avatar.
        dlg = ib.ImageDialog(self, dir_inicial)
        # Centramos el diálogo.
        dlg.Centre()

        if dlg.ShowModal() == wx.ID_OK:
            ruta_fichero = dlg.GetFile()
            bitmap = wx.Bitmap(ruta_fichero, wx.BITMAP_TYPE_ANY)
            self.m_bitmap_avatar.SetBitmap(bitmap)
            # [03-10-2011] Incluimos ruta de imagen.
            self.m_textCtrl_ruta_fich_img.SetValue(ruta_fichero)
        # Limpiamos memoria.
        dlg.Destroy()

    def OnEliminarImagen(self, event):
        '''Event handler para eliminar avatar'''
        self.m_bitmap_avatar.SetBitmap(wx.NullBitmap)
        self.m_textCtrl_ruta_fich_img.SetValue('')

    def OnBorrarREADME(self, event):
        '''Event handler para borrar todo el README'''
        i = wx.MessageBox(t(u"¿Borrar fichero?", self.l), t(u"Atención", self.l), wx.YES_NO)
        if i != wx.YES: return
        self.m_textCtrl_README.SetValue('')

    def OnBorrarHISTORY(self, event):
        '''Event handler para borrar todo el HISTORY'''        
        i = wx.MessageBox(t(u"¿Borrar fichero?", self.l), t(u"Atención", self.l), wx.YES_NO)
        if i != wx.YES: return
        self.m_textCtrl_HISTORY.SetValue('')
        
    def OnCrearREADME(self, event):
        '''Event handler para crear plantilla tipo de README'''        
        enter = '\n'
        ret = t(u'''
------------------------------------------------------------------
Este es el archivo README del proyecto. Aquí, usted debe describir
su proyecto. Dígale al lector (alguien que no sabe nada sobre este 
proyecto) todo lo que él / ella necesita saber. Los comentarios 
por lo general deben incluir al menos:
------------------------------------------------------------------

TÍTULO DEL PROYECTO: 
PROPÓSITO DEL PROYECTO: 
VERSIÓN O FECHA:
CÓMO COMENZAR ESTE PROYECTO: 
AUTORES:
INSTRUCCIONES PARA EL USUARIO:
''', self.l)     
        i = wx.MessageBox(t(u"¿Crear nuevo fichero?", self.l), t(u"Atención", self.l), wx.YES_NO)
        if i != wx.YES: return
        # Incluimos el código.
        self.m_textCtrl_README.SetValue(ret)

    def OnKillFocusIndent(self, event):
        '''Cambiamos la indentación en todos los editores de la aplicación'''
        # Indentación actual.
        indent = self.m_spinCtrl_indentacion.GetValue()
        if indent == 0: 
            wx.MessageBox(t(u"Indentación cero no permitida", self.l),t(u"Atención", self.l), wx.OK)
            return False
        # Cambiamos indentación de panel de código principal.
        self.panel_principal.panel_cod_prin.editor.panel.cambiar_indentacion(indent)
        # Cambiamos indentación de panel de editor de funciones.
        self.panel_principal.panel_editor_func.panel.cambiar_indentacion(indent)
        # Cambiamos indentación de panel de editor de métodos.
        self.panel_principal.panel_met_clases.m_panel_der.panel.cambiar_indentacion(indent)
        # Cambiamos indentación de paneles de constructor y panel de destructor.
        self.panel_principal.panel_dest_clases.editor.panel.cambiar_indentacion(indent)
        self.panel_principal.panel_const_clases.editor_ini.panel.cambiar_indentacion(indent)
        self.panel_principal.panel_const_clases.editor_fin.panel.cambiar_indentacion(indent)        

    # ###########################
    # Event Handlers de licencias
    # ###########################

    def OnCrearLICENSE(self, event):
        '''Se crea contenido de fichero de licencia'''
        i = wx.MessageBox(t(u"¿Crear nuevo fichero?", self.l), t(u"Atención", self.l), wx.YES_NO)
        if i != wx.YES: return

        # Recogemos la licencia seleccionada.
        licencia = self.m_choice_licencias.GetStringSelection()

        # Abrimos fichero...
        datos = f_abrir_ficheros_lic(licencia, self.l)
        if datos is None: return
        datos_plantilla, datos_info = datos
        
        # Pedimos parámetros de configuración.
        a = dialogo_licencias(self, lic_param[licencia], self.l)
        a.Show()
        seguir = True
        if a.ShowModal() == wx.ID_OK:
            propietario = a.m_textCtrl_propietario.GetValue()
            anyo = a.m_textCtrl_anyo.GetValue()
            organizacion = a.m_textCtrl_organizacion.GetValue()
            descripcion = a.m_textCtrl_descripcion.GetValue()
        else:
            seguir = False
        a.Destroy()
        if not seguir: return 
        
        # Formateamos texto y lo incluimos.
        texto_formateado = f_param_lic(datos_plantilla, 
                                       licencia, 
                                       propietario, 
                                       anyo, 
                                       organizacion, 
                                       descripcion)
        self.m_textCtrl_LICENSE.SetValue(texto_formateado)

        # Incluimos el título.
        self.m_textCtrl_titulo.SetValue(licencia)

        # ¿Se generará en cada módulo del proyecto?
        self.m_checkBox_aplic_lic_mod.Set3StateValue(lic_modul[licencia])

    def OnBorrarLICENSE(self, event):
        '''Se elimina contenido de fichero de licencia'''
        i = wx.MessageBox(t(u"¿Borrar fichero?", self.l), t(u"Atención", self.l), wx.YES_NO)
        if i != wx.YES: return
        self.m_textCtrl_LICENSE.SetValue('')
        self.m_checkBox_aplic_lic_mod.Set3StateValue(False)
        self.m_textCtrl_titulo.SetValue('')

    def OnInfoLicencia(self, event):
        '''Se muestra información sobre la licencia seleccionada'''
        # Recogemos la licencia seleccionada.
        licencia = self.m_choice_licencias.GetStringSelection()

        # Abrimos fichero...
        datos = f_abrir_ficheros_lic(licencia, self.l)
        if datos is None: return
        datos_plantilla, datos_info = datos

        # Mostramos información...
        f_mostrar_info(datos_info, licencia)
        
    # ###################################################
    # Event Handlers de generación de ficheros y packages
    # ###################################################

    def OnRutaCarpeta(self, event):
        '''Elegimos ruta de carpeta'''
        carpeta = self.__pedir_carpeta()
        if carpeta is not None:
            self.m_textCtrl_ruta_carpeta.SetValue(carpeta)

    def OnRutaZIP(self, event):
        '''Elegimos ruta para fichero zip'''
        carpeta = self.__pedir_carpeta()
        if carpeta is not None:
            self.m_textCtrl_ruta_zip.SetValue(carpeta)

    def __comprimir(self, nfich_zip, lista_ficheros):
        '''Compresión de ficheros'''
        nfich_zip = nfich_zip.strip()
        if not nfich_zip.endswith('.zip'): nfich_zip += '.zip'
        # Tipo de compresión.
        compresion = zipfile.ZIP_DEFLATED 
        # Creamos un fichero ZIP.
        f_zip = zipfile.ZipFile(file = nfich_zip, 
                                mode = 'w', 
                                compression = compresion, 
                                allowZip64 = False)
        for i in lista_ficheros: 
            f_zip.write(i[0],i[1],compresion)
            # print f_zip.namelist()
        f_zip.close()

    def __crear_carpeta_temporal(self):
        '''Crea carpeta temporal y devuelve su nombre'''
        # Carpeta de creación de datos temporales de la aplicación.
        temp = proy_por_defecto['carpeta_temporal']
        # Nombre de carpeta temporal.
        aux = datetime.datetime.now()
        nombre = str(aux).replace('-','').replace(':','').replace('.','').replace(' ','')
        ret = '%s%s%s' % (temp, proy_por_defecto['sep'], nombre)
        # Creamos carpeta temporal.
        try:
            os.mkdir(ret)
        except:
            msj = t(u"El directorio no se ha creado", self.l)
            wx.MessageBox(msj,t(u"Atención", self.l),wx.OK)
            ret = None
        # Devolvemos nombre de carpeta.
        return ret

    def __eliminar_carpeta_temporal(self, carpeta):
        '''Eliminamos la carpeta pasada como parámetro'''
        try:
            shutil.rmtree(carpeta)
        except:
            msj = u'%s %s' % (t(u"No se pudo eliminar la carpeta temporal", self.l), carpeta)
            wx.MessageBox(msj, t(u"Atención", self.l), wx.OK)
        
    def __crear_modulo_principal(self, crear_modulo_principal,
                                 lista_nombres_modulos):
        '''Verificación de elección de módulo principal'''
        if crear_modulo_principal:
            mod_prin = self.m_comboBox_nombre_modulo.GetStringSelection()
            if lista_nombres_modulos.count(mod_prin) == 0:
                msj = t(u'El módulo principal no es válido', self.l)
                wx.MessageBox(msj, t(u"Atención", self.l), wx.OK)
                return False
        return True
    
    def __crear_fichero(self, ruta_completa, codigo_modulo):
        '''Creación de módulo en disco'''
        # Creamos el fichero y grabamos.
        try:
            f = codecs.open(ruta_completa, 'w', 'utf-8')
            f.write(codigo_modulo)
            f.close()
        except:
            msj = u'%s %s. %s' % (t(u'No se pudo crear el módulo', self.l), ruta_completa, t(u'¿Continuar?', self.l))
            j = wx.MessageBox(msj, t(u"Atención", self.l), wx.YES_NO)
            if j != wx.YES: return False
        return True
    
    def __crear_modulos_py(self, ruta_carpeta):
        '''Crea todos los módulos Python del proyecto'''
        # Guardamos el módulo original para volver a cargarlo después de generar los ficheros.
        modulo_original = self.panel_principal.m_choice_modulos.GetStringSelection()
        # Si se contempla la creación de módulos hay que ver si están.
        for i in self.panel_principal.lista_modulos:
            nombre_modulo = i[0]
            nombre_modulo_aux = i[0] 
            # Cargamos el módulo.
            self.panel_principal.cargar_modulo(nombre_modulo)
            # codigo_modulo = f_codigo_modulo(self.panel_principal, True, idioma = self.l)
            a = codigo_modulo_actual(self.panel_principal, crear_proyecto = True, 
                                     nombre_modulo = nombre_modulo, idioma = self.l)
            codigo_modulo = a.codigo_python_generado()
            del a
            # Le añadimos la extensión al fichero.
            if not nombre_modulo.endswith('.py'): nombre_modulo += '.py'
            ruta_completa = '%s%s%s' % (ruta_carpeta, proy_por_defecto['sep'],
                                        nombre_modulo)
            # Creamos el fichero y grabamos.
            if not self.__crear_fichero(ruta_completa, codigo_modulo): 
                return False
            # ¿Permisos de ejecución al módulo principal?
            self.__crear_modulo_ejecutable(ruta_completa, nombre_modulo_aux)
        # Restauramos módulo original.
        if len(modulo_original.strip()) != 0:
            self.panel_principal.cargar_modulo(modulo_original)
        # Devolvemos estado.
        return True

    def __crear_modulo_py(self, nombre_modulo, ruta_completa):
        '''Crea un único módulo Python pasado como parámetro'''
        # Guardamos el módulo original para volver a cargarlo después de generar los ficheros.
        modulo_original = self.panel_principal.m_choice_modulos.GetStringSelection()
        for i in self.panel_principal.lista_modulos:
            nombre_modulo_actual = i[0]
            if nombre_modulo == nombre_modulo_actual:
                # Cargamos el módulo.
                self.panel_principal.cargar_modulo(nombre_modulo)
                # Creamos código del módulo correspondiente.
                # codigo_modulo = f_codigo_modulo(self.panel_principal, True, idioma = self.l)
                a = codigo_modulo_actual(self.panel_principal, crear_proyecto = True,
                                         nombre_modulo = nombre_modulo, idioma = self.l)
                codigo_modulo = a.codigo_python_generado()
                del a
                # Creamos el fichero y grabamos.
                if not self.__crear_fichero(ruta_completa, codigo_modulo): 
                    return False
                # ¿Permisos de ejecución al módulo principal?
                self.__crear_modulo_ejecutable(ruta_completa, nombre_modulo)
                # Nos salimos.
                break
        # Restauramos módulo original.
        if len(modulo_original.strip()) != 0:
            self.panel_principal.cargar_modulo(modulo_original)
        # Limpiamos.
        # self.panel_principal.limpiar_widget_modulo()
        return True

    def __crear_fichero_base(self, ruta, tipo_fich, texto):
        '''Método para crear fichero extra'''
        try:
            ruta_completa = '%s%s%s' % (ruta, proy_por_defecto['sep'],
                                        tipo_fich)
            f = codecs.open(ruta_completa, 'w', 'utf-8')
            f.write(texto)
            f.close()
        except:
            msj = u'%s %s' % (t(u'No se pudo generar fichero', self.l), tipo_fich)
            wx.MessageBox(msj, t(u"Atención", self.l), wx.OK)
        
    def __crear_fichero_LICENSE(self, ruta):
        '''Método para crear fichero LICENSE'''
        self.__crear_fichero_base(ruta, 
                                  proy_por_defecto['fich_license'],
                                  self.m_textCtrl_LICENSE.GetValue())
            
    def __crear_fichero_README(self, ruta):        
        '''Método para crear fichero README'''
        self.__crear_fichero_base(ruta, 
                                  proy_por_defecto['fich_readme'],
                                  self.m_textCtrl_README.GetValue())

    def __crear_fichero_HISTORY(self, ruta):
        '''Método para crear fichero HISTORY'''
        self.__crear_fichero_base(ruta, 
                                  proy_por_defecto['fich_history'],
                                  self.m_textCtrl_HISTORY.GetValue())
            
    def __crear_carpeta_raiz(self, carpeta, destino, 
                             crear_modulos, crear_init, nfich_zip = None):
        '''Devuelve True si se crea carpeta raíz y False en caso contrario'''
        ruta = '%s%s%s' % (destino, proy_por_defecto['sep'], carpeta)
        if os.path.exists(ruta): 
            if nfich_zip is None:
                msj1 = t(u'La carpeta raíz ya existe', self.l)
                msj2 = t(u'Se sobreescribirán módulos con igual nombre', self.l)
                msj3 = t(u'Se sobreescribirán __init__.py', self.l)
                msj4 = t(u'No se sobreescribirán carpetas con igual nombre', self.l)
                msj = msj1 + enter + msj4 + enter
                if crear_modulos: msj += msj2 + enter
                if crear_init: msj += msj3 + enter
            else:
                if not nfich_zip.endswith('.py'): nfich_zip += '.py'
                aux1 = t(u'Se creará el fichero', self.l)
                aux2 = t(u'en', self.l)
                msj = u'%s %s %s %s%s' % (aux1, nfich_zip, aux2, destino, enter)
                msj += u'Se sobreescribirá fichero con igual nombre'
            msj += u'¿Continuar?'
            i = wx.MessageBox(msj, u"Atención", wx.YES_NO)
            if i != wx.YES: return False
        return True
        
    def __msj_aceptacion(self, nombre_modulos, ruta_carpeta, fichero_zip = None):
        '''Mensaje de aceptación de creación de ficheros'''
        if fichero_zip is None:
            aux1 = t(u'Se crearán los ficheros:', self.l)
            aux2 = t(u'en', self.l)
            msj = u'%s %s%s %s %s%s' % (aux1, enter,
                                        nombre_modulos, 
                                        aux2, ruta_carpeta, enter)
        else:
            fichero_zip = fichero_zip.strip()
            if not fichero_zip.endswith('.zip'): fichero_zip += '.zip'
            aux1 = t(u'será creado', self.l)
            msj = u'%s %s' % (fichero_zip, aux1)
        msj += u'Se sobreescribirán ficheros con mismo nombre. ¿Continuar?' 
        i = wx.MessageBox(msj, u"Atención", wx.YES_NO)
        if i != wx.YES: return False
        return True

    def __crear_package(self, ruta_carpeta, estructura_packages,
                        crear_modulos, crear__init__py,
                        lista_nombres_modulos):
        '''Creación de package'''
        for i in estructura_packages:
            # Es módulo ó directorio.
            tipo = i[0]
            # Dirección relativa, con el separador correcto.
            ruta_relativa = i[1]
            ruta_relativa = ruta_relativa.replace('/', proy_por_defecto['sep'])
            # Quitamos la última barra.
            ruta_relativa = ruta_relativa[0:len(ruta_relativa) - 1]
            # Formamos ruta absoluta.
            ruta = '%s%s%s' % (ruta_carpeta, proy_por_defecto['sep'], ruta_relativa)
            # Creamos módulo ó carpeta, según sea.
            if tipo == 'directorio':
                try: os.mkdir(ruta)
                except: pass
            if tipo == 'directorio' and crear__init__py:
                # Creamos __init__.py vacío.
                nfich_init = '%s%s%s' % (ruta, proy_por_defecto['sep'], '__init__.py')
                codecs.open(nfich_init, 'w', 'utf-8').close()
            if tipo == 'modulo' and crear_modulos:
                # Comprobamos si el módulo del árbol está en el proyecto.
                # Obtenemos módulo del package.
                nombre_modulo = ruta.split(proy_por_defecto['sep'])[-1]
                # Y vemos si está en la lista de módulos.
                if lista_nombres_modulos.count(nombre_modulo):
                    generar_codigo = True
                else:
                    generar_codigo = False
                if not ruta.endswith('.py'): ruta += '.py'
                try:
                    if not generar_codigo:
                        codecs.open(ruta,'w','utf-8').close()
                    else:
                        # Generamos código de módulo.
                        ret = self.__crear_modulo_py(nombre_modulo, ruta)
                        if not ret: return False
                except:
                    aux = t(u'no pudo ser creado. ¿Continuar?', self.l)
                    msj = u'%s %s' % (ruta, aux)
                    k = wx.MessageBox(msj, u"Atención",wx.YES_NO)
                    if k != wx.YES: return False
        # Devolvemos estado.
        return True
    
    def __crear_modulo_ejecutable(self, ruta_completa, modulo):
        '''Método para dar permisos de ejecución al módulo principal (Linux)''' 
        if os.name != 'posix': return
        crear_modulo_principal = self.m_checkBox_mod_prin.Get3StateValue() 
        crear_modulo_ejecutable = self.m_checkBox_crear_mod_eje.Get3StateValue() 
        if crear_modulo_principal and crear_modulo_ejecutable:
            # Módulo principal.
            mod_prin = self.m_comboBox_nombre_modulo.GetStringSelection()
            if modulo == mod_prin:
                # Intentamos cambiar los permisos del módulo.
                try:
                    cadena_ejecucion = 'chmod +x %s' % ruta_completa
                    os.system(cadena_ejecucion)
                except:
                    # msj2 = u'no se pudo dar permisos de ejecución a %s' % ruta_completa
                    # msj1 = u'Se ejecutó "%s", pero' % cadena_ejecucion
                    # msj = msj1 + enter + msj2
                    msj = t(u'No se pudo cambiar permisos con chmod', self.l)
                    wx.MessageBox(msj, u'Atención', wx.OK)
            
    def OnGenerarFicheros(self, event):
        '''Generamos ficheros ó packages'''
        # Recogemos datos para generar módulos/package.
        crear_f_license = self.m_checkBox_crear_LICENSE.Get3StateValue()
        crear_f_readme = self.m_checkBox_crear_README.Get3StateValue()
        crear_f_history = self.m_checkBox_crear_HISTORY.Get3StateValue()
        save_carpeta = self.m_checkBox_carpeta.Get3StateValue()
        save_zip = self.m_checkBox_zip.Get3StateValue()
        ruta_carpeta = self.m_textCtrl_ruta_carpeta.GetValue()
        ruta_zip = self.m_textCtrl_ruta_zip.GetValue()
        f_zip = self.m_textCtrl_nfich_zip.GetValue()
        organizar_en_carpeta = self.m_radioBtn_carpeta.GetValue()
        organizar_en_package = self.m_radioBtn_packages.GetValue()
        crear__init__py = self.m_checkBox_init_py.Get3StateValue()
        crear_modulos = self.m_checkBox_modulos.Get3StateValue()
        crear_modulo_principal = self.m_checkBox_mod_prin.Get3StateValue() 
        crear_modulo_ejecutable = self.m_checkBox_crear_mod_eje.Get3StateValue() 
        # Recogemos estructura de packages.
        estructura_packages = self.panel_principal.panel_packages.salvar_datos()
        # Casos básicos que no pueden darse.
        if organizar_en_package and estructura_packages is None:
            msj = t(u'El árbol de packages está vacío', self.l)
            wx.MessageBox(msj, u"Atención", wx.OK)
            return 
        if save_zip and (len(f_zip.strip()) == 0 or len(ruta_zip.strip()) == 0):
            msj = t(u"Falta especificar nombre de fichero ZIP y/o su ruta", self.l)
            wx.MessageBox(msj, u"Atención", wx.OK)
            return 
        if save_carpeta and len(ruta_carpeta.strip()) == 0:
            msj = t(u"Falta especificar ruta de carpeta", self.l)
            wx.MessageBox(msj, u"Atención", wx.OK)
            return 
        if not organizar_en_carpeta and not organizar_en_package:
            msj = t(u"Se debe de elegir una forma de organizar el código", self.l)
            wx.MessageBox(msj, u"Atención", wx.OK)
            return
        elif not save_carpeta and not save_zip:
            msj = t(u"Se debe de elegir la forma de guardar el código", self.l)
            wx.MessageBox(msj, u"Atención", wx.OK)
            return
        # Creamos lista de nombres de módulos.
        #nhojas = self.modulos.GetPageCount()
        nombre_modulos = ''
        lista_nombres_modulos = list()
        for i in self.panel_principal.lista_modulos:
            nombre_modulos += '%s.py%s' % (i[0], enter)
            lista_nombres_modulos.append(i[0])
        # Y nombres de otros ficheros...
        if crear_f_license: nombre_modulos += '%s%s' % (proy_por_defecto['fich_license'],enter)
        if crear_f_readme: nombre_modulos += '%s%s' % (proy_por_defecto['fich_readme'], enter)
        if crear_f_history: nombre_modulos += '%s%s' % (proy_por_defecto['fich_history'], enter)
        # #########################################################
        # Organizar código en carpeta, guardando código en carpeta.
        # #########################################################
        if organizar_en_carpeta and save_carpeta:
            # Mensaje de aceptación de creación de ficheros.
            ret = self.__msj_aceptacion(nombre_modulos, ruta_carpeta)
            if not ret: return
            # El módulo principal debe ser correcto, si lo hay.
            ret = self.__crear_modulo_principal(crear_modulo_principal, 
                                                lista_nombres_modulos)
            if not ret: return
            # Para cada módulo, creamos el fichero correspondiente.
            ret = self.__crear_modulos_py(ruta_carpeta)
            if not ret: return
            # Creamos restantes ficheros, si procede.
            if crear_f_license: self.__crear_fichero_LICENSE(ruta_carpeta)
            if crear_f_readme: self.__crear_fichero_README(ruta_carpeta)
            if crear_f_history: self.__crear_fichero_HISTORY(ruta_carpeta)
        # #############################################################
        # Organizar código en carpeta, guardando código en fichero ZIP.
        # #############################################################
        if organizar_en_carpeta and save_zip:
            # Mensaje de aceptación de creación de ficheros.
            ret = self.__msj_aceptacion(nombre_modulos, ruta_zip, f_zip)
            if not ret: return
            # El módulo principal debe ser correcto, si lo hay.
            ret = self.__crear_modulo_principal(crear_modulo_principal, 
                                                lista_nombres_modulos)
            if not ret: return
            # Creamos un directorio temporal.
            ruta_dir_temp = self.__crear_carpeta_temporal()
            if ruta_dir_temp is None: return
            # Para cada módulo, creamos el fichero correspondiente.
            ret = self.__crear_modulos_py(ruta_dir_temp)
            if not ret: return
            # Creamos lista de ficheros a comprimir.
            lista_fich_a_comprimir = list()
            for nombre_modulo in lista_nombres_modulos:
                if not nombre_modulo.endswith('.py'): nombre_modulo += '.py'
                ret = '%s%s%s' % (ruta_dir_temp, proy_por_defecto['sep'],
                                  nombre_modulo)
                lista_fich_a_comprimir.append((ret, nombre_modulo))
            # Creamos restantes ficheros, si procede.
            if crear_f_license: 
                self.__crear_fichero_LICENSE(ruta_dir_temp)
                # Lo añadimos a la lista de ficheros a comprimir.
                ret = '%s%s%s' % (ruta_dir_temp, proy_por_defecto['sep'],
                                  proy_por_defecto['fich_license'])
                lista_fich_a_comprimir.append((ret, proy_por_defecto['fich_license']))
            if crear_f_readme: 
                self.__crear_fichero_README(ruta_dir_temp)
                # Lo añadimos a la lista de ficheros a comprimir.
                ret = '%s%s%s' % (ruta_dir_temp, proy_por_defecto['sep'],
                                  proy_por_defecto['fich_readme'])
                lista_fich_a_comprimir.append((ret, proy_por_defecto['fich_readme']))
            if crear_f_history: 
                self.__crear_fichero_HISTORY(ruta_dir_temp)
                # Lo añadimos a la lista de ficheros a comprimir.
                ret = '%s%s%s' % (ruta_dir_temp, proy_por_defecto['sep'],
                                  proy_por_defecto['fich_history'])
                lista_fich_a_comprimir.append((ret, proy_por_defecto['fich_history']))
            # Fichero a comprimir.
            f_zip_aux = '%s%s%s' % (ruta_zip, proy_por_defecto['sep'], f_zip)
            # Comprimimos módulos.
            self.__comprimir(f_zip_aux, lista_fich_a_comprimir)
            # Eliminamos directorio temporal.
            self.__eliminar_carpeta_temporal(ruta_dir_temp)
        # #########################################################
        # Organizar código en package, guardando código en carpeta.
        # #########################################################
        if organizar_en_package and save_carpeta:
            # Comprobamos si se puede crear raíz en destino.
            carpeta_raiz = estructura_packages[0][1].split('/')[0]
            if not self.__crear_carpeta_raiz(carpeta_raiz, 
                                             ruta_carpeta,
                                             crear_modulos,
                                             crear__init__py): return 
            # El módulo principal debe ser correcto, si lo hay.
            if crear_modulos:
                ret = self.__crear_modulo_principal(crear_modulo_principal, 
                                                    lista_nombres_modulos)
                if not ret: return
            # Creamos estructura de package.
            ret = self.__crear_package(ruta_carpeta, estructura_packages,
                                       crear_modulos, crear__init__py,
                                       lista_nombres_modulos)
            if not ret: return
            # Creamos restantes ficheros, si procede.
            ruta_aux = ruta_carpeta + proy_por_defecto['sep'] + carpeta_raiz
            if crear_f_license: self.__crear_fichero_LICENSE(ruta_aux)
            if crear_f_readme: self.__crear_fichero_README(ruta_aux)
            if crear_f_history: self.__crear_fichero_HISTORY(ruta_aux)
        # #############################################################
        # Organizar código en package, guardando código en fichero ZIP.
        # #############################################################
        if organizar_en_package and save_zip:
            # Comprobamos si se puede crear raíz en destino.
            carpeta_raiz = estructura_packages[0][1].split('/')[0]
            if not self.__crear_carpeta_raiz(carpeta_raiz, 
                                             ruta_carpeta,
                                             crear_modulos,
                                             crear__init__py,f_zip): return 
            # El módulo principal debe ser correcto, si lo hay.
            if crear_modulos:
                ret = self.__crear_modulo_principal(crear_modulo_principal, 
                                                    lista_nombres_modulos)
                if not ret: return
            # Creamos un directorio temporal.
            ruta_dir_temp = self.__crear_carpeta_temporal()
            if ruta_dir_temp is None: return
            # Creamos estructura de package.
            ret = self.__crear_package(ruta_dir_temp, estructura_packages,
                                       crear_modulos, crear__init__py,
                                       lista_nombres_modulos)
            if not ret: return
            # Creamos restantes ficheros, si procede.
            ruta_aux = ruta_dir_temp + proy_por_defecto['sep'] + carpeta_raiz
            if crear_f_license: self.__crear_fichero_LICENSE(ruta_aux)
            if crear_f_readme: self.__crear_fichero_README(ruta_aux)
            if crear_f_history: self.__crear_fichero_HISTORY(ruta_aux)
            # Creamos lista de ficheros a comprimir.
            lista_fich_a_comprimir = list()
            for root, dirs, files in os.walk(ruta_dir_temp): 
                for i in files:
                    ruta_aux = root + proy_por_defecto['sep'] + i
                    modulo_aux = proy_por_defecto['sep'].join(ruta_aux.split(proy_por_defecto['sep'])[2:])
                    lista_fich_a_comprimir.append((ruta_aux, modulo_aux))
            # Fichero a comprimir.
            f_zip_aux = '%s%s%s' % (ruta_zip, proy_por_defecto['sep'], f_zip)
            # Comprimimos módulos.
            self.__comprimir(f_zip_aux, lista_fich_a_comprimir)                        
            # Eliminamos directorio temporal.
            self.__eliminar_carpeta_temporal(ruta_dir_temp)
            
        # Info de finalización de proceso.
        msj = t(u'¡Ficheros generados!', self.l)
        wx.MessageBox(msj, t(u'Información', self.l), wx.OK)

    # ##########################################################
    # Event Handler para generación de documentaćión de proyecto
    # ##########################################################

    def __crear_fichero_doc(self, ruta_completa, texto):
        '''Creación de fichero de documentación'''
        seguir = True
        try:
            f = codecs.open(ruta_completa, 'w', 'utf-8')
            f.write(texto)
            f.close()
        except: 
            seguir = False
        # Devolvemos estado.
        return seguir
    
    def generar_bmp_ogl(self, terminacion):
        '''Crea imagen bmp a partir de diagrama ogl, y devuelve su ruta'''
        try:
            alto = self.m_spinCtrl_alto_ogl.GetValue()
            ancho = self.m_spinCtrl_ancho_ogl.GetValue()
            # Creamos imagen vacía.
            imagen = wx.EmptyBitmap(ancho, alto)
            # Creamos Device Context y le asignamos el wx.Bitmap.
            dc = wx.MemoryDC()
            dc.SelectObject(imagen)        
            # Cambiamos el color de fondo.
            dc.SetBackground(wx.Brush(wx.Colour(127,127,127)))
            dc.Clear()
            # Capturamos el contenido.
            self.panel_principal.panel_ogl.panel.canvas.GetDiagram().Redraw(dc)
            # Formamos fichero.
            nombre_fichero = '%s%sf_%s_diagrama_clases.bmp' % \
                           (proy_por_defecto['carpeta_temporal'], proy_por_defecto['sep'],
                            str(terminacion))
            imagen.SaveFile(nombre_fichero, wx.BITMAP_TYPE_BMP)
            # Limpiamos memoria.
            del dc
            # Devolvemos ruta.
            return os.path.realpath(nombre_fichero)
        except:
            return None
        
    def __generar_doc_proyecto(self):
        '''Generación de datos de proyecto.'''
        if self.m_checkBox_proyecto_doc.Get3StateValue():
            # Definición.
            if self.m_checkList_proy_doc.IsChecked(0):
                # Recogemos datos individuales.
                nombre = self.m_textCtrl_nproy.GetValue()
                version = self.m_textCtrl_version.GetValue()
                fecha_creacion = str(self.m_datePicker_creacion.GetValue().Format('%d-%m-%Y'))
                grupo = self.m_textCtrl_grupo.GetValue()
                desarrollador = self.m_textCtrl_desarrollador.GetValue()
                nick = self.m_textCtrl_nick.GetValue() 
                # Y formamos elemento.
                definicion = [nombre, version, fecha_creacion, nick, desarrollador, grupo]
            else: definicion = None
            # Objetivo.
            if self.m_checkList_proy_doc.IsChecked(1):
                objetivo = self.m_textCtrl_objetivo.GetValue()
            else: objetivo = None
            # Notas.
            if self.m_checkList_proy_doc.IsChecked(2):
                notas = self.m_textCtrl_notas.GetValue()
            else: notas = None
            # Avatar.
            if self.m_checkList_proy_doc.IsChecked(3):
                avatar = self.m_textCtrl_ruta_fich_img.GetValue()
            else: avatar = None
            # README.
            if self.m_checkList_proy_doc.IsChecked(4):
                readme = self.m_textCtrl_README.GetValue()
            else: readme = None
            # LICENSE.
            if self.m_checkList_proy_doc.IsChecked(5):
                licencia = self.m_textCtrl_LICENSE.GetValue()
            else: licencia = None
            # HISTORY.
            if self.m_checkList_proy_doc.IsChecked(6):
                history = self.m_textCtrl_HISTORY.GetValue()
            else: history = None
            # Datos a devolver.
            datos = [definicion, readme, history, 
                     licencia, objetivo, notas, avatar]
        else: 
            datos = None
        # Devolvemos datos.
        return datos

    def __generar_fichero_aux(self, texto, ruta_completa):
        '''Método auxiliar para generar ficheros de documentación'''
        # Generamos fichero.
        if len(texto.strip()) == 0:
            msj = t(u'¡Hay que seleccionar documentación a generar y formato de salida!', self.l)
            wx.MessageBox(msj, t(u"Atención", self.l), wx.OK)
            return False
        else:
            if not self.__crear_fichero_doc(ruta_completa, texto):
                msj = t(u'No se pudo generar el fichero', self.l) 
                wx.MessageBox(msj, t(u'Atención', self.l), wx.OK)
                return False
            else:
                msj = t(u'Se creó el fichero de documentación', self.l) 
                wx.MessageBox(msj, t(u'Atención', self.l), wx.OK)
        return True
    
    def __generar_package_texto_old(self):
        '''Generación de packages del proyecto'''
        if self.m_checkBox_packages_doc.Get3StateValue():
            estructura_packages = self.packages.salvar_datos()
            ret = ''
            for i in estructura_packages: 
                aux = i[1].split('/')
                long_ruta = len(aux) - 2
                if i[0] == 'modulo':
                    aux2 = i[1][0:len(i[1]) - 1]
                    if not aux2.endswith('.py'): aux3 = aux2 + '.py'
                    else: aux3 = aux2
                else: aux3 = i[1]
                ret += long_ruta * " " * 4 + aux3 + enter
            return ret
        else:
            return None

    def __generar_package_texto(self):
        '''Generación de packages del proyecto'''
        if self.m_checkBox_packages_doc.Get3StateValue():
            estructura_packages = self.panel_principal.panel_packages.salvar_datos()
            if estructura_packages is None or len(estructura_packages) == 0: return t(u'Sin packages', self.l)
            ret_lista = list()
            ret = ''
            for i in estructura_packages: 
                # Identificamos módulo .py.
                if i[0] == 'modulo':
                    aux2 = i[1][0:len(i[1]) - 1]
                    if not aux2.endswith('.py'): aux3 = aux2 + '.py'
                    else: aux3 = aux2
                else: aux3 = i[1]
                ret_lista.append(aux3)
            # Formateamos el árbol, creando profundidad de las ramas.
            nodo_raiz = ret_lista[0] # Nodo raíz.
            for i in ret_lista[1:]:
                # Creamos nodos de rama.
                aux = i.split("/")
                # Nodo final.
                nodo_final = aux[-1]
                rama = aux[-2::-1]
                espacio = ""
                if len(nodo_final.strip()) == 0: 
                    nodo_final = aux[-2]
                    rama = aux[-3::-1]
                    espacio = ""
                # Contamos caracteres de cada rama.
                contador = 0
                for j in rama:
                    contador += len(j)
                # Formamos nueva rama.
                nueva_rama = (contador * " ") + espacio + "/" + nodo_final
                ret += nueva_rama + (enter * 2)
            # Incluimos nodo raíz.
            ret = '/' + nodo_raiz[0:len(nodo_raiz)-1] + (enter * 2) + ret
            return ret
        else:
            return None

    def __hereda_de(self, nombre, clases, relacion):
        '''Búsqueda de las clases de las que hereda la clase actual'''
        hereda_de = list()
        for j in relacion.relaciones():
            # print "j = %s, nombre = %s" % (j, nombre)
            if j[2] == nombre:
                # Clase de la que hereda.
                clase_p = unicode(j[1]).strip()
                # Buscamos los parámetros de instanciación
                # de la clase de la que hereda.
                param2 = None
                for k in clases:
                    if k[0].nombre == clase_p:
                        param2 = None if len(k[0].parametros) == 0 else k[0].parametros
                        break
                # Formamos los parámetros de inicialización.
                aux2 = []
                if param2 is None:
                    # Incluimos en la lista de clases a heredar.
                    hereda_de.append([clase_p, None])
                else:
                    for l in param2:
                        if len(unicode(l[1]).strip()) != 0:
                            elem = '%s = %s' % (l[0], l[1])
                        else:
                            elem = l[0]
                        aux2.append(elem)
                    # Incluimos en la lista de clases a heredar.
                    hereda_de.append([clase_p, aux2])
        # Devolvemos lista.
        return hereda_de
        
    def __generar_doc_modulo(self):
        '''Generación de datos de módulo.'''
        # Comprobamos si hay módulos seleccionados
        if self.m_checkBox_modulos_doc.Get3StateValue():
            # Elementos de módulo chequeados.
            elem_modulo = list()
            # Incluimos índices de elementos.
            nelem = self.m_checkList_elem_mod_doc.GetCount()
            for i in range(nelem):
                if self.m_checkList_elem_mod_doc.IsChecked(i):
                    elem_modulo.append(i)
            # Para cada módulo chequeado hay que construir
            # los datos a partir de lo seleccionado en los
            # elementos de módulo.
            modulos_a_documentar = list()
            modulos = self.m_checkList_mod_doc.GetStrings() 
            indice = 0
            for i in modulos:
                # ¿Está chequeado?
                if self.m_checkList_mod_doc.IsChecked(indice):
                    modulos_a_documentar.append(i)
                # Aumentamos el índice.
                indice += 1
            # Definimos estructura que contendrá todos los módulos con 
            # toda la información, pendiente de formatear:
            # ret_modulos = [
            # [modulo, clases, funciones, documentacion, imports, registros, constantes, cod. prin], ...]
            # donde clases = [(nombre, hereda_de, clases_externas, comentario, constantes,
            #                  propiedades, atributos, metodos), ...]
            # funciones = [(nombre, 65, comentario, pre, post, lista_param, codigo), ...]
            ret_modulos = list()
            # Terminación de ficheros de diagramas de clases.
            bmp_a_ogl = 0
            # Guardamos el módulo original para volver a cargarlo después de generar la doc.
            modulo_original = self.panel_principal.m_choice_modulos.GetStringSelection()
            # Recorremos todos los módulos, obteniendo los datos
            # a partir de los módulos y elementos seleccionados.
            for i in self.panel_principal.lista_modulos:
                # Aumentamos terminación.
                bmp_a_ogl += 1
                # Módulo.
                modulo_actual = i[0]
                if not modulo_actual in modulos_a_documentar:
                    continue
                # Cargamos el módulo.
                self.panel_principal.cargar_modulo(modulo_actual)
                # ¿Clases? Índice 5.
                if 5 in elem_modulo:
                    # Panel de clases.
                    clases = self.panel_principal.panel_ogl.modelo.clases() 
                    relacion = self.panel_principal.panel_ogl.relacion
                    # Bolsa de las clases del módulo actual.
                    clases_modulo_actual = list()
                    # Recorremos todas las clases.
                    for clase in clases:
                        # Recogemos datos que definen la clase.
                        nombre = clase[0].nombre
                        hereda_de =  self.__hereda_de(clase[0].nombre, clases, relacion)
                        clases_externas = clase[0].clases_externas
                        comentario = clase[0].comentario
                        atributos = clase[0].atributos
                        metodos = clase[0].metodos
                        propiedades = clase[0].propiedades            
                        constantes = clase[0].constantes
                        parametros = clase[0].parametros
                        # Añadimos clase a la bolsa de clases.
                        clases_modulo_actual.append((nombre, hereda_de, clases_externas, comentario,
                                                     constantes, propiedades, atributos, metodos, parametros))
                else: clases_modulo_actual = None
                # ¿Funciones? Índice 4.
                if 4 in elem_modulo:
                    # Panel de funciones.
                    funciones = self.panel_principal.panel_param_func.salvar_datos()
                else: funciones = None
                # ¿Documentación? Índice 0.
                if 0 in elem_modulo:
                    # Panel de documentación.
                    documentacion = self.panel_principal.panel_doc.salvar_datos()
                else: documentacion = None
                # ¿Imports? Índice 1.
                if 1 in elem_modulo:
                    # Panel de imports.
                    imports = self.panel_principal.panel_imports.salvar_datos()
                else: imports = None
                # ¿Registros? Índice 3.
                if 3 in elem_modulo:
                    # Panel de registros.
                    registros = self.panel_principal.panel_registros.salvar_datos()
                else: registros = None
                # ¿Constantes? Índice 2.
                if 2 in elem_modulo:
                    # Panel de constantes.
                    constantes = self.panel_principal.panel_ctes.salvar_datos()
                else: constantes = None
                # ¿Código principal? Índice 7.
                if 7 in elem_modulo:
                    # Panel de código principal.
                    codigo_modulo = self.panel_principal.panel_cod_prin.salvar_datos()
                else: codigo_modulo = None
                # Diagrama de clases.
                if 6 in elem_modulo:
                    # Crear diagrama de clases.
                    ruta_bmp_ogl = self.generar_bmp_ogl(bmp_a_ogl)
                else: ruta_bmp_ogl = None
                # Incluimos módulo en lista de módulos.
                ret_modulos.append([modulo_actual, clases_modulo_actual, funciones,
                                    documentacion, imports, registros, constantes,
                                    codigo_modulo, ruta_bmp_ogl])
            # Restauramos módulo original.
            if len(modulo_original.strip()) != 0:
                self.panel_principal.cargar_modulo(modulo_original)
            # Devolvemos módulos con sus datos correspondientes.
            if len(ret_modulos) == 0: ret_modulos = None
            return ret_modulos
        else: 
            return None

    def OnGenerarDoc(self, event):
        '''Generación de documentación del proyecto'''
        if not self.m_checkBox_TXT_doc.Get3StateValue() and \
           not self.m_checkBox_HTML_doc.Get3StateValue():
            wx.MessageBox(t(u"Seleccione salida de documentación", self.l), t(u"Atención", self.l), wx.OK)
        # Proceso de generación de documentación en txt y html. 
        # Texto...
        if self.m_checkBox_TXT_doc.Get3StateValue():
            texto = ''
            if len(self.m_textCtrl_nombre_txt_doc.GetValue().strip()) != 0 and \
               len(self.m_textCtrl_ruta_doc_txt.GetValue().strip()) != 0:
                # Datos 
                # Recogemos datos del proyecto.
                datos = self.__generar_doc_proyecto()
                if datos is not None:
                    # Generamos documentación de proyecto.
                    doc1 = doc_proyecto(datos, 'txt')
                    texto += doc1.devolver_texto()
                    del doc1
                # Recogemos datos de packages.
                datos = self.__generar_package_texto()
                if datos is not None:
                    # Generamos documentación de packages.
                    doc1 = doc_packages(datos, 'txt')
                    texto += doc1.devolver_texto()
                    del doc1
                # Recogemos datos de módulos.
                datos = self.__generar_doc_modulo()
                if datos is not None:
                    # Generamos documentación de módulos.
                    doc1 = doc_modulos(datos, 'txt')
                    texto += doc1.devolver_texto()
                    del doc1
                # Datos de salida de fichero.
                ruta = self.m_textCtrl_ruta_doc_txt.GetValue()
                nombre_fichero = self.m_textCtrl_nombre_txt_doc.GetValue()
                if not nombre_fichero.endswith('.txt'): nombre_fichero += '.txt'
            else:
                msj = t(u'Se debe incluir nombre y ruta de fichero de texto.', self.l)
                wx.MessageBox(msj, t(u'Atención', self.l), wx.OK)
                return 
            # Ruta completa del fichero.
            ruta_completa = ruta + proy_por_defecto['sep'] + nombre_fichero
            # Generamos fichero.
            if not self.__generar_fichero_aux(texto, ruta_completa): return
            # Previsualizar.
            f_mostrar_info(texto, t(u"Documentación", self.l))
        # HTML...
        if self.m_checkBox_HTML_doc.Get3StateValue():
            texto = ''
            if len(self.m_textCtrl_nombre_html_doc.GetValue().strip()) != 0 and \
               len(self.m_textCtrl_ruta_doc_html.GetValue().strip()) != 0:
                # Recogemos datos del proyecto.
                datos = self.__generar_doc_proyecto()
                if datos is not None:
                    # Generamos documentación de proyecto.
                    doc1 = doc_proyecto(datos, 'html')
                    texto += doc1.devolver_texto()
                    del doc1
                # Recogemos datos de packages.
                datos = self.__generar_package_texto()
                if datos is not None:
                    # Generamos documentación de packages.
                    if len(texto.strip()) == 0:
                        doc1 = doc_packages(datos, 'html')
                    else:
                        # Si ya hay texto, no se incluye cabecera.
                        doc1 = doc_packages(datos, 'html', False)
                    texto += doc1.devolver_texto()
                    del doc1
                # Recogemos datos de módulos.
                datos = self.__generar_doc_modulo()
                if datos is not None:
                    # Generamos documentación de módulos.
                    if len(texto.strip()) == 0:
                        doc1 = doc_modulos(datos, 'html')
                    else:
                        # Si ya hay texto, no se incluye cabecera.
                        doc1 = doc_modulos(datos, 'html', False)
                    texto += doc1.devolver_texto()
                    del doc1
                # Cerramos html, si hay texto.
                if len(texto.strip()) !=0:
                    a = doc_base(None, None)
                    texto += a.pie_html()
                    del a
                # Datos de salida de fichero.
                ruta = self.m_textCtrl_ruta_doc_html.GetValue()
                nombre_fichero = self.m_textCtrl_nombre_html_doc.GetValue()
                if not nombre_fichero.endswith('.html'): nombre_fichero += '.html'
            else:
                msj = t(u'Se debe incluir nombre y ruta de fichero html', self.l)
                wx.MessageBox(msj, t(u'Atención', self.l), wx.OK)
                return 
            # Ruta completa del fichero.
            ruta_completa = ruta + proy_por_defecto['sep'] + nombre_fichero
            # Generamos fichero.
            # texto_parseado = self.__parsear_a_html(texto)
            if not self.__generar_fichero_aux(texto, ruta_completa): return
            # Previsualizamos.
            # Lanzamos la pagina web en el navegador por defecto.
            lanzadera_web = enlace_web.HyperLinkCtrl(self, -1)
            lanzadera_web.Show(False)
            lanzadera_web.GotoURL(os.path.realpath(ruta_completa), True, False)    
            # Nos limpiamos el objeto lanzadera.
            lanzadera_web.Destroy()
    
    def OnRutaDocTXT(self, parent):
        '''Elegimos ruta de carpeta para TXT'''
        carpeta = self.__pedir_carpeta()
        if carpeta is not None:
            self.m_textCtrl_ruta_doc_txt.SetValue(carpeta)

    def OnRutaDocHTML(self, parent):
        '''Elegimos ruta de carpeta para HTML'''
        carpeta = self.__pedir_carpeta()
        if carpeta is not None:
            self.m_textCtrl_ruta_doc_html.SetValue(carpeta)
            
    def limpiar_widget(self):
        '''Limpiar datos de configuración.'''
        self.m_textCtrl_nproy.SetValue('')
        self.m_datePicker_creacion.SetValue(wx.DateTime.Now()) 
        self.m_textCtrl_version.SetValue('')
        self.m_textCtrl_desarrollador.SetValue('')
        self.m_textCtrl_nick.SetValue('') # Nick
        self.m_textCtrl_grupo.SetValue('')
        self.m_textCtrl_objetivo.SetValue('')
        self.m_textCtrl_README.SetValue('')
        self.m_checkBox_crear_README.Set3StateValue(wx.CHK_UNCHECKED)
        self.m_textCtrl_LICENSE.SetValue('') # Licencias
        self.m_choice_licencias.SetSelection(0) # Licencias
        self.m_checkBox_crear_LICENSE.Set3StateValue(wx.CHK_UNCHECKED) # Licencias
        self.m_textCtrl_titulo.SetValue('') # Licencias
        self.m_checkBox_aplic_lic_mod.Set3StateValue(wx.CHK_UNCHECKED) # Licencias
        self.m_textCtrl_notas.SetValue('') # Notas
        self.m_textCtrl_HISTORY.SetValue('') # Historial.
        self.m_bitmap_avatar.SetBitmap(wx.NullBitmap) # Avatar
        self.m_textCtrl_ruta_fich_img.SetValue('') # Avatar
        self.m_checkBox_carpeta.Set3StateValue(wx.CHK_UNCHECKED) # Carpeta.
        self.m_textCtrl_ruta_carpeta.SetValue('') # Ruta carpeta
        self.m_checkBox_zip.Set3StateValue(wx.CHK_UNCHECKED) # ZIP.
        self.m_textCtrl_nfich_zip.SetValue('') # Nombre de fichero ZIP.
        self.m_textCtrl_ruta_zip.SetValue('') # Ruta ZIP
        self.m_radioBtn_carpeta.SetValue(False) # Organizar en carpeta.
        self.m_radioBtn_packages.SetValue(False) # Organizar en packages.
        self.m_checkBox_init_py.Set3StateValue(wx.CHK_CHECKED) # Crear init.py en packages.
        self.m_checkBox_modulos.Set3StateValue(wx.CHK_CHECKED) # Incluir módulos en packages.
        self.m_spinCtrl_indentacion.SetValue(proy_por_defecto['indentacion'])
        self.m_textCtrl_codif.SetValue(proy_por_defecto['codificacion'])
        self.m_checkBox_mod_prin.Set3StateValue(wx.CHK_UNCHECKED)
        self.m_comboBox_nombre_modulo.SetItems(list()) # Lista de módulos que pueden ser principales.
        self.m_checkBox_script_eje.Set3StateValue(wx.CHK_UNCHECKED)
        self.m_textCtrl_script_eje.SetValue(proy_por_defecto['script_eje_unix'])
        self.m_checkBox_crear_mod_eje.Set3StateValue(wx.CHK_UNCHECKED)
        self.m_checkBox_cabecera_vipera.Set3StateValue(wx.CHK_CHECKED)
        # Se incluyen elementos de documentación.
        self.m_checkBox_proyecto_doc.Set3StateValue(wx.CHK_CHECKED)
        self.m_checkBox_modulos_doc.Set3StateValue(wx.CHK_CHECKED)
        self.m_checkBox_packages_doc.Set3StateValue(wx.CHK_CHECKED)
        self.m_textCtrl_ruta_doc_txt.SetValue('')
        self.m_textCtrl_ruta_doc_html.SetValue('')
        self.m_textCtrl_nombre_html_doc.SetValue('')
        self.m_textCtrl_nombre_txt_doc.SetValue('')
        self.m_checkBox_TXT_doc.Set3StateValue(wx.CHK_UNCHECKED)
        self.m_checkBox_HTML_doc.Set3StateValue(wx.CHK_UNCHECKED)
        self.__seleccionar_items_doc()

    def __seleccionar_items_doc(self):
        '''Selecciona todos los items de los checkList de documentación'''
        nelem = self.m_checkList_elem_mod_doc.GetCount()
        self.m_checkList_elem_mod_doc.SetChecked(range(nelem))
        nelem = self.m_checkList_proy_doc.GetCount()
        self.m_checkList_proy_doc.SetChecked(range(nelem))
        
    def cargar_nombres_modulos_en_doc(self, opcion = 0):
        '''Carga de nombres de módulos en área de documentación'''
        modulos = list()
        for i in self.panel_principal.lista_modulos: modulos.append(i[0])
        if opcion == 0:
            # Recargamos lista de módulos para elegir módulo principal.
            modulo_actual = self.m_comboBox_nombre_modulo.GetStringSelection()
            self.m_comboBox_nombre_modulo.SetItems(modulos)
            self.m_comboBox_nombre_modulo.SetStringSelection(modulo_actual)
            # Recarcamos lista de módulos de documentación.
            self.m_checkList_mod_doc.SetItems(modulos)
            # Y por defecto los activamos todos.
            nelem = self.m_checkList_mod_doc.GetCount()
            self.m_checkList_mod_doc.SetChecked(range(nelem))
            
    def cargar_datos_extra_proyecto(self):
        '''Activar elementos y carga de nombre de módulos en documentación'''
        # Por defecto todo está activado en la documentación.
        self.__seleccionar_items_doc()
        # Cargamos nombres de módulos en el lugar correspondiente.
        self.cargar_nombres_modulos_en_doc()
        
    def cargar_datos(self, x_conf_proyecto):
        '''Carga de datos en los widgets'''
        # Incluimos datos.
        self.m_textCtrl_nproy.SetValue(x_conf_proyecto['nombre_proyecto'])
        dia, mes, anyo = x_conf_proyecto['fecha_creacion'].split('-')
        fecha = wx.DateTimeFromDMY(int(dia), int(mes) - 1, int(anyo))
        self.m_datePicker_creacion.SetValue(fecha)
        self.m_textCtrl_version.SetValue(x_conf_proyecto['version'])
        self.m_textCtrl_desarrollador.SetValue(x_conf_proyecto['desarrollador'])
        self.m_textCtrl_grupo.SetValue(x_conf_proyecto['grupo'])
        self.m_textCtrl_objetivo.SetValue(x_conf_proyecto['objetivo'])
        self.m_textCtrl_README.SetValue(x_conf_proyecto['readme'])
        self.m_checkBox_crear_README.Set3StateValue(x_conf_proyecto['check_readme'])
        self.m_textCtrl_HISTORY.SetValue(x_conf_proyecto['history'])
        self.m_checkBox_crear_HISTORY.Set3StateValue(x_conf_proyecto['check_history'])
        self.m_spinCtrl_indentacion.SetValue(x_conf_proyecto['indentacion'])
        self.m_textCtrl_codif.SetValue(x_conf_proyecto['codificacion'])
        self.m_checkBox_mod_prin.Set3StateValue(x_conf_proyecto['crear_mod_principal'])
        self.m_comboBox_nombre_modulo.SetItems([x_conf_proyecto['nombre_mod_principal']]) # Lista...
        self.m_comboBox_nombre_modulo.SetStringSelection(x_conf_proyecto['nombre_mod_principal'])
        self.m_checkBox_script_eje.Set3StateValue(x_conf_proyecto['es_script_ejecutable'])
        self.m_textCtrl_script_eje.SetValue(x_conf_proyecto['script_ejecutable'])
        self.m_checkBox_crear_mod_eje.Set3StateValue(x_conf_proyecto['crear_mod_ejecutable'])
        self.m_checkBox_cabecera_vipera.Set3StateValue(x_conf_proyecto['cabecera_vipera'])
        self.m_textCtrl_nick.SetValue(x_conf_proyecto['nick']) # Nick.
        self.m_textCtrl_LICENSE.SetValue(x_conf_proyecto['licencia']) # Licencias
        self.m_checkBox_crear_LICENSE.Set3StateValue(x_conf_proyecto['licencia_crear_f']) # Licencias
        self.m_textCtrl_titulo.SetValue(x_conf_proyecto['licencia_titulo']) # Licencias
        self.m_checkBox_aplic_lic_mod.Set3StateValue(x_conf_proyecto['licencia_modulos_py']) # Licencias
        self.m_choice_licencias.SetStringSelection(x_conf_proyecto['licencia_tipos']) # Licencias.
        self.m_textCtrl_notas.SetValue(x_conf_proyecto['notas']) # Notas
        # Avatar. Obtener imagen de fichero serializado con cPickle.
        avatar = x_conf_proyecto['avatar']
        if avatar is not None:
            avatar_nombre_fich = '%s' % x_conf_proyecto['avatar_nombre_fich']
            # Formamos ruta de fichero de imagen.
            aux = u'%s%s%s' % (proy_por_defecto['carpeta_temporal'], proy_por_defecto['sep'], avatar_nombre_fich)
            ruta_fichero_imagen = os.path.realpath(aux)
            # Creamos fichero de imagen temporal.
            imagen = open(ruta_fichero_imagen,'wb')
            imagen.write(avatar)
            imagen.close()
            bitmap = wx.Bitmap(ruta_fichero_imagen, wx.BITMAP_TYPE_ANY)
            self.m_bitmap_avatar.SetBitmap(bitmap) # Avatar
            self.m_textCtrl_ruta_fich_img.SetValue(ruta_fichero_imagen)
        else:
            self.m_bitmap_avatar.SetBitmap(wx.NullBitmap) # Avatar
            self.m_textCtrl_ruta_fich_img.SetValue('')
        # Datos de generación de ficheros de código...
        self.m_checkBox_carpeta.Set3StateValue(x_conf_proyecto['carpeta']) # Carpeta.
        self.m_textCtrl_ruta_carpeta.SetValue(x_conf_proyecto['ruta_carpeta']) # Ruta carpeta
        self.m_checkBox_zip.Set3StateValue(x_conf_proyecto['fichero_zip']) # ZIP.
        self.m_textCtrl_nfich_zip.SetValue(x_conf_proyecto['nfich_zip']) # Nombre de fichero ZIP.
        self.m_textCtrl_ruta_zip.SetValue(x_conf_proyecto['ruta_zip']) # Ruta ZIP
        self.m_radioBtn_carpeta.SetValue(x_conf_proyecto['organizar_en_carpeta']) # Organizar en carpeta.
        self.m_radioBtn_packages.SetValue(x_conf_proyecto['organizar_en_packages']) # Organizar en packages.
        self.m_checkBox_init_py.Set3StateValue(x_conf_proyecto['crear_init_py']) # Crear init.py en packages.
        self.m_checkBox_modulos.Set3StateValue(x_conf_proyecto['crear_modulos']) # Incluir módulos en packages.
        # Documentación...
        self.m_checkBox_proyecto_doc.Set3StateValue(x_conf_proyecto['proyecto_doc'])
        self.m_checkBox_modulos_doc.Set3StateValue(x_conf_proyecto['modulos_doc'])
        self.m_checkBox_packages_doc.Set3StateValue(x_conf_proyecto['packages_doc'])
        self.m_textCtrl_ruta_doc_txt.SetValue(x_conf_proyecto['ruta_doc_txt'])
        self.m_textCtrl_ruta_doc_html.SetValue(x_conf_proyecto['ruta_doc_html'])
        self.m_textCtrl_nombre_html_doc.SetValue(x_conf_proyecto['nombre_html_doc'])
        self.m_textCtrl_nombre_txt_doc.SetValue(x_conf_proyecto['nombre_txt_doc'])
        self.m_checkBox_TXT_doc.Set3StateValue(x_conf_proyecto['TXT_doc'])
        self.m_checkBox_HTML_doc.Set3StateValue(x_conf_proyecto['HTML_doc'])
        self.m_checkList_elem_mod_doc.DeselectAll() # Deseleccionamos todo...
        self.m_checkList_proy_doc.DeselectAll() # Deseleccionamos todo...
        self.m_checkList_elem_mod_doc.SetChecked(x_conf_proyecto['elem_mod_doc'])
        self.m_checkList_proy_doc.SetChecked(x_conf_proyecto['proy_doc'])
        self.m_spinCtrl_alto_ogl.SetValue(x_conf_proyecto['alto_ogl'])
        self.m_spinCtrl_ancho_ogl.SetValue(x_conf_proyecto['ancho_ogl'])

    def salvar_datos(self):
        '''Método que recorre los datos del proyecto y los devuelve en un diccionario'''                
        nombre_proyecto = self.m_textCtrl_nproy.GetValue()
        fecha_creacion = unicode(self.m_datePicker_creacion.GetValue().Format('%d-%m-%Y'))
        version = self.m_textCtrl_version.GetValue()
        desarrollador = self.m_textCtrl_desarrollador.GetValue()
        nick = self.m_textCtrl_nick.GetValue() # Nick.
        licencia = self.m_textCtrl_LICENSE.GetValue() # Licencias
        licencia_crear_f = self.m_checkBox_crear_LICENSE.Get3StateValue() # Licencias
        licencia_titulo = self.m_textCtrl_titulo.GetValue() # Licencias
        licencia_modulos_py = self.m_checkBox_aplic_lic_mod.Get3StateValue() # Licencias
        licencia_tipos = self.m_choice_licencias.GetStringSelection() # Licencias.
        notas = self.m_textCtrl_notas.GetValue() # Notas
        # Avatar. Serializar imagen con cPickle.
        ruta_fichero_imagen = self.m_textCtrl_ruta_fich_img.GetValue() 
        if len(ruta_fichero_imagen) != 0:
            try:
                fichero_imagen = open(ruta_fichero_imagen,'rb')
                avatar = fichero_imagen.read()
                fichero_imagen.close()
                avatar_nombre_fich = os.path.basename(ruta_fichero_imagen)
            except:
                avatar_nombre_fich = None
                avatar = None
        else:
            avatar_nombre_fich = None
            avatar = None
        # Demás datos...
        grupo = self.m_textCtrl_grupo.GetValue()
        objetivo = self.m_textCtrl_objetivo.GetValue()
        readme = self.m_textCtrl_README.GetValue()
        check_readme = self.m_checkBox_crear_README.Get3StateValue()
        check_history = self.m_checkBox_crear_HISTORY.Get3StateValue() # Historial.
        history = self.m_textCtrl_HISTORY.GetValue() # Historial.
        indentacion = self.m_spinCtrl_indentacion.GetValue()
        codificacion = self.m_textCtrl_codif.GetValue()
        crear_mod_principal = self.m_checkBox_mod_prin.Get3StateValue()
        nombre_mod_principal = self.m_comboBox_nombre_modulo.GetStringSelection() # Mód. prin.
        es_script_ejecutable = self.m_checkBox_script_eje.Get3StateValue()
        script_ejecutable = self.m_textCtrl_script_eje.GetValue()
        crear_mod_ejecutable = self.m_checkBox_crear_mod_eje.Get3StateValue()
        cabecera_vipera = self.m_checkBox_cabecera_vipera.Get3StateValue()
        carpeta = self.m_checkBox_carpeta.Get3StateValue() # Carpeta.
        ruta_carpeta = self.m_textCtrl_ruta_carpeta.GetValue() # Ruta carpeta
        fichero_zip = self.m_checkBox_zip.Get3StateValue() # ZIP.
        nfich_zip = self.m_textCtrl_nfich_zip.GetValue() # Nombre de fichero ZIP.
        ruta_zip = self.m_textCtrl_ruta_zip.GetValue() # Ruta ZIP
        organizar_en_carpeta = self.m_radioBtn_carpeta.GetValue() # Organizar en carpeta.
        organizar_en_packages = self.m_radioBtn_packages.GetValue() # Organizar en packages.
        crear_init_py = self.m_checkBox_init_py.Get3StateValue() # Crear init.py en packages.
        crear_modulos = self.m_checkBox_modulos.Get3StateValue() # Incluir módulos en packages.
        # Configuración de la documentación.
        proyecto_doc = self.m_checkBox_proyecto_doc.Get3StateValue()
        modulos_doc = self.m_checkBox_modulos_doc.Get3StateValue()
        packages_doc = self.m_checkBox_packages_doc.Get3StateValue()
        ruta_doc_txt = self.m_textCtrl_ruta_doc_txt.GetValue()
        ruta_doc_html = self.m_textCtrl_ruta_doc_html.GetValue()
        nombre_html_doc = self.m_textCtrl_nombre_html_doc.GetValue()
        nombre_txt_doc = self.m_textCtrl_nombre_txt_doc.GetValue()
        TXT_doc = self.m_checkBox_TXT_doc.Get3StateValue()
        HTML_doc = self.m_checkBox_HTML_doc.Get3StateValue()
        nelem = self.m_checkList_elem_mod_doc.GetCount()
        elem_mod_doc = list()
        for i in range(nelem): 
            if self.m_checkList_elem_mod_doc.IsChecked(i): 
                elem_mod_doc.append(i)
        nelem = self.m_checkList_proy_doc.GetCount()
        proy_doc = list()
        for i in range(nelem): 
            if self.m_checkList_proy_doc.IsChecked(i): 
                proy_doc.append(i)
        alto_ogl = self.m_spinCtrl_alto_ogl.GetValue()
        ancho_ogl = self.m_spinCtrl_ancho_ogl.GetValue()
        # Creamos diccionario de configuración del proyecto.
        x_conf_proyecto = {'nombre_proyecto' : nombre_proyecto,
                           'fecha_creacion' : fecha_creacion,
                           'version' : version,
                           'desarrollador' : desarrollador,
                           'grupo' : grupo,
                           'objetivo' : objetivo,
                           'readme' : readme,
                           'check_readme' : check_readme,
                           'history' : history,
                           'check_history' : check_history,
                           'indentacion' : indentacion,
                           'codificacion' : codificacion,
                           'crear_mod_principal' : crear_mod_principal,
                           'nombre_mod_principal' : nombre_mod_principal,
                           'es_script_ejecutable' : es_script_ejecutable,
                           'script_ejecutable' : script_ejecutable,
                           'crear_mod_ejecutable' : crear_mod_ejecutable,
                           'cabecera_vipera' : cabecera_vipera,
                           'nick' : nick, 
                           'avatar' : avatar,
                           'avatar_nombre_fich' : avatar_nombre_fich,
                           'notas' : notas,
                           'licencia' : licencia,
                           'licencia_crear_f' : licencia_crear_f,
                           'licencia_titulo' : licencia_titulo,
                           'licencia_modulos_py' : licencia_modulos_py,
                           'licencia_tipos' : licencia_tipos,
                           'carpeta' : carpeta,
                           'ruta_carpeta' : ruta_carpeta,
                           'fichero_zip' : fichero_zip,
                           'nfich_zip' : nfich_zip,
                           'ruta_zip' : ruta_zip,
                           'organizar_en_carpeta' : organizar_en_carpeta,
                           'organizar_en_packages' : organizar_en_packages,
                           'crear_init_py' : crear_init_py,
                           'crear_modulos' : crear_modulos,
                           'packages_doc' : packages_doc,
                           'proyecto_doc' : proyecto_doc,
                           'modulos_doc' : modulos_doc,
                           'ruta_doc_txt' : ruta_doc_txt,
                           'ruta_doc_html' : ruta_doc_html,
                           'nombre_html_doc' : nombre_html_doc,
                           'nombre_txt_doc' : nombre_txt_doc,
                           'elem_mod_doc' : elem_mod_doc,
                           'proy_doc' : proy_doc,
                           'TXT_doc' : TXT_doc,
                           'HTML_doc' : HTML_doc,
                           'alto_ogl': alto_ogl,
                           'ancho_ogl' : ancho_ogl}
        return x_conf_proyecto
        